package com.atguigu.gulimall.product.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.utils.HttpUtils;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.feign.memberFeignService;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.Catelog2Vo;
import com.atguigu.gulimall.product.vo.GiteeAccessToken;
import com.atguigu.gulimall.product.vo.GiteeUserInfo;
import com.atguigu.gulimall.product.vo.MemberEntityVo;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class indexController {

    @Autowired
    CategoryService categoryService;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    memberFeignService memberFeignService;

    /**
     * 停车
     * @return
     * @throws InterruptedException
     */
    @ResponseBody
    @RequestMapping("park")
    public String park() throws InterruptedException {

        RSemaphore semaphore = redissonClient.getSemaphore("park");
        //阻塞式
//        semaphore.acquire();
        //非阻塞
        boolean flag = semaphore.tryAcquire();
        String s="";
        if (flag){
            s= "acquire ok";
        }else {
            s="acquire false";
        }
        return s;

    }



    /**
     * 开车
     * @return
     * @throws InterruptedException
     */
    @ResponseBody
    @RequestMapping("notPark")
    public String notPark() throws InterruptedException {

        RSemaphore semaphore = redissonClient.getSemaphore("park");
        //阻塞式(释放)
        semaphore.release();
        return "relase ok";

    }



    @RequestMapping("/lock")
    @ResponseBody
    public String lock() throws InterruptedException {

        RCountDownLatch latch = redissonClient.getCountDownLatch("class");
        latch.trySetCount(5);
        latch.await();
        return "lock success";

    }

    @RequestMapping("/gogogo/{id}")
    @ResponseBody
    public String gogogo(@PathVariable("id") long id){
        RCountDownLatch latch = redissonClient.getCountDownLatch("class");
        latch.countDown();

        return  id+"gogogo";

    }

















//    @ResponseBody
    @RequestMapping("/hello")
    @ResponseBody
    public String testRedisson(){
        //获取一个可重入锁
        RLock lock = redissonClient.getLock("my-lock");
        //上锁
        lock.lock(); //阻塞式等待。默认加的锁的时间都是30s时间。
        //1)、锁的自动续期，如果业务的时间超长，运行期间就会给锁进行自动续期30s。所以不用担心业务的时间长，锁自动过期会被删掉
        //2)、加锁的业务只要运行完成，就不会给当锁续期，即使不手动解锁，锁默认在30s后就会自动删除。

        //
        lock.lock(10, TimeUnit.SECONDS);    //10s以后自动解锁，自动解锁的时间一定要大于业务的执行时间
        //1)、问题：lock.lock(10, TimeUnit.SECONDS); 在锁的时间到了以后不会自动续期，
        //2)、如果我们传递了锁的超时时间，就会给redis执行lua脚本，进行占锁，默认的超时时间就是我们指定的时间。
        //只要占锁成功，就会启动一个定时任务[重新给锁设置过期的时间，新的过期时间就是看门狗的默认时间]，每隔10s都会自动自动续期30s
        //internalLoclLeaseTime:看门狗时间： /3 ,10s


        //实战实用
        //1) lock.lock(10,TIMEUNIT.SECONDS);省去了续期的操作
        System.out.println("加锁成功："+Thread.currentThread().getId());
        try {
            System.out.println("执行业务代码。。。");
            Thread.sleep(30000);

        }catch (Exception e){
        }finally {
            //解锁
            lock.unlock();
            System.out.println("释放锁成功。。。"+Thread.currentThread().getId());
        }

        return "hello";

    }



    @RequestMapping("/testReadLock")
    @ResponseBody
    public void testReadLock(){

        RReadWriteLock lock = redissonClient.getReadWriteLock("re-wr-lock");
        //上读锁
        RLock rLock = lock.readLock();
        rLock.lock();
        try {
            System.out.println("读锁上锁");
            String s = redisTemplate.opsForValue().get("readWriteLock");
            System.out.println(s);
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //解锁
            rLock.unlock();
            System.out.println("读锁释放锁");
        }

    }


    @ResponseBody
    @RequestMapping("/testWriteLock")
    public void testWriteLock(){

        RReadWriteLock lock = redissonClient.getReadWriteLock("re-wr-lock");
        RLock rLock = lock.writeLock();
        rLock.lock();
        try {
            System.out.println("写锁加锁");
            String s = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set("readWriteLock",s);
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //解锁
            rLock.unlock();
            System.out.println("写锁释放锁");
        }


    }







    @RequestMapping({"/", "/index"})
    public String indexRequest(Model model) {
        //查询出所有的一级分类
        List<CategoryEntity> categoryEntityList = categoryService.getAllLevel1();
        model.addAttribute("categoryEntityList", categoryEntityList);
        return "index";
    }


    //渲染二级和三级分类
    @ResponseBody
    @RequestMapping("/index/catalog.json")
    public  Map<String, List<Catelog2Vo>> getLeve2AndLevel3(){
//        Map<String, List<Catelog2Vo>> level23Data = categoryService.getLevel23Data();
        Map<String, List<Catelog2Vo>> fromCache = categoryService.getLevel23DataWithSpringCache();
        return fromCache;
    }


//    @ResponseBody
//    @GetMapping("/oauth2.0/gitee/success")
//    public String gitee(@RequestParam("code") String code) throws Exception {
////        HashMap<String, Object> paraMap = new HashMap<>();
////        paraMap.put("code",code);
////        System.out.println("回调收集来的code为:"+code);
////        return code;
//        Map<String,String> bodys = new HashMap<>();
//        bodys.put("grant_type","authorization_code");
//        bodys.put("code",code);
//        bodys.put("client_id","932392466e048f7662a7a85a177fe802bbad5939a72a41bbd6dccb35e5c26186");
//        bodys.put("redirect_uri","http://gulimall.com/oauth2.0/gitee/success");
//        bodys.put("client_secret","cf882e621119dce6d67acb210e751e67c7a5d97141390cdcfa81762b73b44006");
//        //1.根据code换取GiteeAccessToken;
//        HttpResponse response_GiteeAccesstoken = HttpUtils.doPost("https://gitee.com", "/oauth/token", "post", new HashMap(), new HashMap(), bodys);
//
//        //处理返回值
//        if(response_GiteeAccesstoken.getStatusLine().getStatusCode() == 200){
//            //获取到了GiteeAccessToken
//            MemberEntityVo memberEntityVo = new MemberEntityVo();
//            String tokenJson = EntityUtils.toString(response_GiteeAccesstoken.getEntity());
//            JSONObject jsonObject = JSON.parseObject(tokenJson);
//            System.out.println(jsonObject);
//            GiteeAccessToken token = JSON.parseObject(tokenJson, GiteeAccessToken.class);
//            //根据Token，通过查询Gitee Open Api获取用户信息
//            Map<String,String> query = new HashMap<>();
//            query.put("access_token", token.getAccess_token());
//            memberEntityVo.setAccess_token(token.getAccess_token());
//            memberEntityVo.setExpiresIn(token.getExpires_in()+"");
//            try {
//                HttpResponse response_userInfo = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", new HashMap(), query);
//                String giteeUserInfoJson = EntityUtils.toString(response_userInfo.getEntity());
//                GiteeUserInfo giteeUserInfo = JSON.parseObject(giteeUserInfoJson, GiteeUserInfo.class);
//                System.out.println("giteeUserInfo:"+giteeUserInfo);
//                memberEntityVo.setSocialUid(giteeUserInfo.getId()+"");
//                memberEntityVo.setNickname(giteeUserInfo.getName());
//            }catch (Exception exception){
//
//            }
//
//            //登录或者注册这个社交用户
//            //1.当前用户如果是第一次进入网站，就自动注册（为当前社交用户生成一个会员信息账号，以后这个社交账号就对应指定的会员）
//
//            R r = memberFeignService.dealSocialLogin(memberEntityVo);
//            if (r.getCode()==0){
//                //注册或者登录成功
//                TypeReference<MemberEntityVo> typeReference = new TypeReference<MemberEntityVo>() {
//                };
//                //获取远程注册的结果
//                MemberEntityVo entityVo = r.getData(typeReference);
//                System.out.println("远程返回的结果:"+entityVo);
//
//            }else {
//
//
//            }
//
//        }else {
//            return "redirect:http://auth.gulimall.com/login.html";
//        }
//
//        //2.登录成功后跳回首页
//        return "redirect:http://gulimall.com";
//
//
//    }


}
